package SWFData;

import java.io.BufferedWriter;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
import java.util.Vector;

import myio.FileIO;
import mymath.MyMathOps;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import Learn.clusterparser;

public class SWFdatamanager extends Data.datamanager{




private class plantlist{

	Vector<String> plantnames;
	/*
	 * Maps the plant identifiers to consecutive indices 
	 */
	TreeMap<Integer,Integer> idtoindex;
	
	private plantlist(String mrffile){
		plantnames = new Vector<String>();
		idtoindex = new TreeMap<Integer,Integer>();
		
		SAXReader reader = new SAXReader();
		try{
		File xmlfile = new File(mrffile);
		Document doc = reader.read(xmlfile);
		Element root = doc.getRootElement();
		
		Element preamel = root.element("MetaData");
		Element plantvars = preamel.element("DiscreteVariables");
		List<Element> plantvarslist = preamel.elements("DiscreteVariable");
		
		int plantcount = 0;
			for (Iterator<Element> i = plantvars.elementIterator("DiscreteVariable"); i.hasNext();plantcount++){
				Element plantel = i.next();
				plantnames.add(plantel.attributeValue("Name").replaceAll(" ", "_"));
				idtoindex.put(Integer.parseInt(plantel.attributeValue("ID")),plantcount);
			}
		}
		catch (Exception e) {
			System.err.println(e);
		}
	}
	
	private int size(){
		return plantnames.size();
	}
	
	private String getName(int ind){
		return plantnames.get(ind);
	}
	
	private int getIndForID(int ID){
		return idtoindex.get(ID);
	}
	
}

String sourcefile = null;
plantlist mypl = null;
int[][] data;


public void plotPlant(String mapfile, int plantind, String outfilename){
	/* The first component of plantdata is a dummy element for
	 * compatibility with the clusterindices arrays 
	 */
	int[] plantdata = new int[data.length+2];
	for (int i=0;i < data.length;i++){
		plantdata[i+2]= data[i][plantind];
	}
	makeXFIGmap(mapfile,plantdata,outfilename);
}


/* Creates a colored map in xfig format. 
 * mapfile is a datafile in .mrf format that 
 * supplies in its <Points> fields the polygon
 * vertices defining the sites. clsterindices is 
 * an array with 2 + as many entries as there are
 * <Site> elements in the mapfile.  
 * 
 * The first two entries in clusterindices (clustertype) are not used here
 */
public static void makeXFIGmap(String mapfile, int[] clusterindices, String outfilename ){


	try{
		SAXReader reader = new SAXReader();
		File xmlfile = new File(mapfile);
		Document doc = reader.read(xmlfile);
		Element root = doc.getRootElement();



			/* Prepare the outputfile: */
			BufferedWriter figwriter = FileIO.openOutputFile(outfilename);
			figwriter.write("#FIG 3.2" + '\n' + 
					"Landscape" + '\n' + 
					"Center" + '\n' + 
					"Metric" + '\n' + 
					"A4"      + '\n' + 
					"100.00" + '\n' + 
					"Single" + '\n' + 
					"-2 "+ '\n' + 
					"1200 2" + '\n' +
					"0 50 #007599"   + '\n' +
					"0 51 #5da591"   + '\n' +
					"0 52 #fca537"   + '\n' +
					"0 53 #7f6b37"   + '\n' +
					"0 54 #a2ff00"   + '\n' +
					"0 55 #a2ffff"   + '\n' +
					"0 56 #ffff1b"   + '\n' +
					"0 57 #c5b3ff"   + '\n' +
					"0 58 #c5b318"   + '\n' 
			);

			/* Iterate over all sites */
			Element sitesel = root.element("Sites");
			int siteno = 0;
			for (Iterator<Element> i = sitesel.elementIterator("Site");i.hasNext();siteno++){
				Element siteel = i.next();
				Element polygonel = siteel.element("Points");
				//System.out.print(siteno + ": "); 
				List<Element> pointlist = polygonel.elements("Point");
				figwriter.write("2 3 0 1 0 ");
				int col = 50 + clusterindices[2+siteno];
				figwriter.write(col + " ");
				figwriter.write("50 -1 20 0.000 0 0 -1 0 0 " + pointlist.size() + '\n');

				for (Iterator<Element> ii = pointlist.iterator();ii.hasNext();){
					Element pointel = ii.next();
					int xcoord = Integer.parseInt(pointel.attributeValue("X"));
					int ycoord = Integer.parseInt(pointel.attributeValue("Y"));
					figwriter.write(xcoord + " " + ycoord + " ");
				}
				figwriter.write('\n');
			}

			figwriter.close();
	}
	catch (Exception e) {
		System.err.println(e);
	}
}

public void plotClusterings(int[][] clusterings, String baseoutname){
	System.out.println("plot clusterings to " + baseoutname);
	for (int layer=0;layer<clusterings.length-1;layer++){
		makeXFIGmap(sourcefile, clusterings[layer], baseoutname+layer+".fig");
	}
	makeXFIGmap(sourcefile, clusterings[clusterings.length-1], baseoutname+"combined.fig");
}

public int[][] clusterout2xfig(String clusfile){
	/* Reading the clustering information */
	int[][] clusterings = clusterparser.readClusters(clusfile);
	
	/* Writing the xfig maps: */
	String baseoutname = clusfile +"_layer_";
	for (int layer=0;layer<clusterings.length-1;layer++){
		makeXFIGmap(sourcefile, clusterings[layer], baseoutname+layer+".fig");
	}
	makeXFIGmap(sourcefile, clusterings[clusterings.length-1], baseoutname+"combined.fig");
	return clusterings;
}

//public void initplantlist(String sourcefile){
//	mypl = new plantlist(sourcefile);
//}

/* requires mypl to be initialized !*/
public void loadData(String sf){
	sourcefile = sf;
	mypl = new plantlist(sourcefile);
	SAXReader reader = new SAXReader();
	try{
		File xmlfile = new File(sourcefile);
		Document doc = reader.read(xmlfile);
		Element root = doc.getRootElement();

		Element sitesel = root.element("Sites");
		List<Element> sitelist = sitesel.elements("Site");

		data = new int[sitelist.size()][mypl.size()];

		int caseno = 0;
		for (Iterator<Element> i = sitelist.iterator();i.hasNext();caseno++){
			Element siteel = i.next();
			Element variables = siteel.element("DiscreteVariables");
			for (Iterator<Element> ii = variables.elementIterator("DiscreteVariable");ii.hasNext();){
				Element variable = ii.next();
				int value = Integer.parseInt(variable.attributeValue("Value"));
				if ( value == 3 || value ==2)
					data[caseno][mypl.getIndForID(Integer.parseInt(variable.attributeValue("ID")))]=1;
			}
		}
	}
	catch (Exception e) {
		System.err.println(e);
	}
}

public int[][] getData(){
	return data;
}

public int getdataitem(int site, int plant){
	return data[site][plant];
}

public int numAttributes(){
	return mypl.size();
}

public int numInstances(){
	return data.length;
}

public void processClusteroutput(String resultfile){
	clusterout2xfig(resultfile);
}
public String getAttributeName(int ind){
	return mypl.getName(ind);
}

}
